package com.nostop.service;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.nostop.mapper.SysAclModuleMapper;
import com.nostop.mapper.SysDeptMapper;
import com.nostop.model.SysAcl;
import com.nostop.model.SysAclModule;
import com.nostop.model.SysDept;
import com.nostop.util.LevelUtil;
import com.nostop.vo.AclDto;
import com.nostop.vo.AclModuleLevelDto;
import com.nostop.vo.DeptLevelVo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysTreeService {

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private SysAclModuleMapper sysAclModuleMapper;

    @Resource
    private SysCoreService sysCoreService;

    public List<AclModuleLevelDto> roleTree(int roleId){
        //1.当前用户已经分配的权限点
        List<SysAcl> userAclList = sysCoreService.getCurrentUserAclList();
        //2.当前角色已经分配的权限
        List<SysAcl> roleAclList = sysCoreService.getRoleAclList(roleId);
        //遍历map中的第一个对象的id组成list然后转换成set
        Set<Integer> userAclIdSet = userAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());
        //角色已分配的id的集合
        Set<Integer> roleAclIdSet = roleAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());
        //取userAclIdSet和roleAclIdSet的并集
        Set<SysAcl> aclSet = new HashSet<>(roleAclList);
        //这里的前提条件是sysAcl里面加了@EqualsAndHashCode注解
        aclSet.addAll(userAclList);
        List<AclDto> aclDtoList = Lists.newArrayList();
        for (SysAcl acl : aclSet) {
            AclDto dto = AclDto.adapt(acl);
            if(userAclIdSet.contains(acl.getId())){
                dto.setHasAcl(true);
            }
            if(roleAclIdSet.contains(acl.getId())) {
                dto.setChecked(true);
            }
            aclDtoList.add(dto);
        }
        return aclListToTree(aclDtoList);
    }

    public List<AclModuleLevelDto> aclListToTree(List<AclDto> aclDtoList) {
        if(CollectionUtils.isEmpty(aclDtoList)) {
            return Lists.newArrayList();
        }
        List<AclModuleLevelDto> aclModuleLevelDtoList = aclModuleTree();
        //每个模块下面对应的权限点列表
        Multimap<Integer,AclDto> modeleIdAclMap = ArrayListMultimap.create();
        for(SysAcl acl : aclDtoList) {
            if(acl.getStatus() == 1) {
                modeleIdAclMap.put(acl.getAclModuleId(),AclDto.adapt(acl));
            }
        }
        return aclModuleLevelDtoList;
    }

    public List<AclModuleLevelDto> aclModuleTree() {
        List<SysAclModule> aclModuleList = sysAclModuleMapper.getAllAclModule();
        List<AclModuleLevelDto> dtoList = Lists.newArrayList();
        for (SysAclModule aclModule : aclModuleList) {
            dtoList.add(AclModuleLevelDto.adapt(aclModule));
        }
        return aclModuleListToTree(dtoList);
    }

    public List<AclModuleLevelDto> aclModuleListToTree(List<AclModuleLevelDto> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return Lists.newArrayList();
        }
        //会创建出一个key为level,value为DeptLevelVoList,它是专门存储这种类型的map<String,List<T>>
        //level -> [aclmodule,aclmodule2,..] map<String,List<Object>>
        Multimap<String,AclModuleLevelDto> levelAclModuleMap = ArrayListMultimap.create();
        List<AclModuleLevelDto> rootList =Lists.newArrayList();
        for (AclModuleLevelDto dto : dtoList) {
            levelAclModuleMap.put(dto.getLevel(),dto);
            if (LevelUtil.ROOT.equals(dto.getLevel())){
                rootList.add(dto);
            }
        }
        //排序
        Collections.sort(rootList,aclModuleSeqComparator);
        transformAclModuleTree(rootList,LevelUtil.ROOT,levelAclModuleMap);
        return rootList;
    }

    //转换成树形结构
    public void transformAclModuleTree(List<AclModuleLevelDto> dtoList,String level,Multimap<String,AclModuleLevelDto> levelAclModuleMap) {
        for (int i = 0;i<dtoList.size();i++) {
            AclModuleLevelDto dto = dtoList.get(i);
            String nextLevel = LevelUtil.calculateLevel(level,dto.getId());
            List<AclModuleLevelDto> tempList = (List<AclModuleLevelDto>) levelAclModuleMap.get(nextLevel);
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tempList)) {
                Collections.sort(tempList,aclModuleSeqComparator);
                dto.setAclModuleList(tempList);
                transformAclModuleTree(tempList,nextLevel,levelAclModuleMap);
            }

        }
    }


    public List<DeptLevelVo> deptTree() {
        List<SysDept> deptList =sysDeptMapper.getAllDept();
        List<DeptLevelVo> deptLevelVoList =Lists.newArrayList();
        for (SysDept dept : deptList) {
            DeptLevelVo deptLevelVo = DeptLevelVo.adapt(dept);
            deptLevelVoList.add(deptLevelVo);
        }
        return deptListToTree(deptLevelVoList);
    }

    public List<DeptLevelVo> deptListToTree(List<DeptLevelVo> deptLevelVoList) {
        if (CollectionUtils.isEmpty(deptLevelVoList)) {
            return Lists.newArrayList();
        }
        //会创建出一个key为level,value为DeptLevelVoList,它是专门存储这种类型的map<String,List<T>>
        Multimap<String,DeptLevelVo> levelDeptMap = ArrayListMultimap.create();
        List<DeptLevelVo> rootList =Lists.newArrayList();
        for (DeptLevelVo dto : deptLevelVoList) {
            levelDeptMap.put(dto.getLevel(),dto);
            if (LevelUtil.ROOT.equals(dto.getLevel())){
                rootList.add(dto);
            }
        }
        //按照seq从小到大排序
        Collections.sort(rootList, new Comparator<DeptLevelVo>() {
            public int compare(DeptLevelVo o1, DeptLevelVo o2) {
                return o1.getSeq() - o2.getSeq();
            }
        });
        //递归生成树
        transformDeptTree(rootList,LevelUtil.ROOT,levelDeptMap);
        return rootList;
    }

    //递归排序下面的值
    public void transformDeptTree(List<DeptLevelVo> deptLevelVoList, String level,Multimap<String,DeptLevelVo> levelVoMultimap) {
        for (int i=0; i < deptLevelVoList.size(); i++) {
            //遍历该层的每个元素
            DeptLevelVo deptLevelVo = deptLevelVoList.get(i);
            //处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level,deptLevelVo.getId());
            //去处理下一层
            List<DeptLevelVo> tempDeptList = (List<DeptLevelVo>) levelVoMultimap.get(nextLevel);
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tempDeptList)) {
                //排序
                Collections.sort(tempDeptList, deptSeqComparator);
                //设置下一层部门
                deptLevelVo.setDeptList(tempDeptList);
                //进入到下一层处理
                transformDeptTree(tempDeptList,nextLevel,levelVoMultimap);
            }
        }
    }

    public Comparator<DeptLevelVo> deptSeqComparator = new Comparator<DeptLevelVo>() {
        @Override
        public int compare(DeptLevelVo o1, DeptLevelVo o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

    public Comparator<AclModuleLevelDto> aclModuleSeqComparator = new Comparator<AclModuleLevelDto>() {
        @Override
        public int compare(AclModuleLevelDto o1, AclModuleLevelDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

}
